/*
*********************************************************************************************************
*                                DSP Driver for MCU
*
*                   (c) Copyright 2025 - 2025; Fortemedia Inc.; Nanjing, China
*
*                   All rights reserved.  Protected by international copyright laws.
*                   Knowledge of the source code may not be used to write a similar
*                   product.  This file may only be used in accordance with a license
*                   and should not be redistributed in any way.
*********************************************************************************************************
*/
#ifndef __DRV_DSP_H
#define __DRV_DSP_H
#ifdef __cplusplus
extern "C" {
#endif
#if 0
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#endif
#include "ej_fm1505_phy.h"
#include "common_def.h"
#ifdef SUPPORT_FM1505_DMS

#define SPI_BUS_ERR              179u
#define TIMEOUT_SPI_BUS              1000
#define DRAM_START_ADDR 0x0FD80000
#define IRAM_START_ADDR 0x10040000
#define COMM_SCENE_FLAG  0x028C
#define DSP_VEC_STEP_2B  2 
#define BLOCK_HEADER_SIZE 6
#define BLOCK_DATA_SIZE 1024
#define BLOCK_SEND_SIZE (BLOCK_HEADER_SIZE+BLOCK_DATA_SIZE)
typedef enum
{
  I2C_addr                = 0xFF, 
  DSP_ID                  = 5051,
  EMB_DATA_SIZE_RAM       = 240,
  EMB_DATA_NUM_RAM        = 16,     
  EMB_DATA_SIZEr_EEPROM   = 128,
  EMB_DATA_NUM_EEPROM     = 7,
  EMB_DATA_SIZE_RAM_I2C   = 4000,
  ATTRI_LOAD_RAM          = 31,
  ATTRI_LOAD_RAM_I2C      = 30,
  ATTRI_LOAD_EEPROM       = 21,
  ATTRI_SPI_DSP_LOAD_VEN_PARAM  =   32, 
  ATTRI_SPI_DSP_LOAD_AFE_PARAM  =   33, 
  EMB_DATA_SIZE           = 4000, 
  EMB_DATA_NUM            = 1,
  ATTRI_LOAD_IRAM         = 52,
  ATTRI_LOAD_DRAM         = 51,
  BURST_READ_WRITE_SIZE   = 512,
  VOS_BASE_ADDR = 0x0FD88010, 
  dram_start_addr = 0x0FD80000,
  dram_end_addr   = 0x0FFFFFFF, 
  iram_start_addr = 0x10040000,  
  iram_end_addr   = 0x1FFFFFFF, 
  fm1288_start_addr = 0x2000,
  fm1288_end_addr   = 0x3FFF

} dsp_chip;
typedef enum
{
  DSP_FW_VER_ADDR         = VOS_BASE_ADDR + 0x00,
  FM_ALG_VER_BASE_ADDR    = VOS_BASE_ADDR + 0x04,
  FM_ALG_PARAM_BASE_ADDR  = VOS_BASE_ADDR + 0x08,
  AFE_CNF_BASE_ADDR       = VOS_BASE_ADDR + 0x0C,
  SYS_CNF_BASE_ADDR       = VOS_BASE_ADDR + 0x10,
  COMM_INFO_BASE_ADDR     = VOS_BASE_ADDR + 0x14,
  SYS_DBG_BASE_ADDR       = VOS_BASE_ADDR + 0x18,
  SPI_CONFIG_BASE_ADDR    = VOS_BASE_ADDR + 0x1C,
  MCUDSP_SPI_SHARE_INFO_BASE_ADDR  = VOS_BASE_ADDR + 0x20,
  DVFS_CONFIG_BASE_ADDR   = VOS_BASE_ADDR + 0x24,
  IM301_CNF_BASE_ADDR     = VOS_BASE_ADDR + 0x28,
  IM301_PARAM_BASE_ADDR   = VOS_BASE_ADDR + 0x2C
} dsp_chip_LUT;

typedef enum
{
  AUTO_VEN_VERSION   = 0,
  AOAA_SW_VERSION    = 4,
  AOAA_VEN_VERSION   = 8,
  ISD_SW_VERSION     = 0x0C,
  IM301_LIB_VERSION  = 0x10
} en_chip_ALG_VER_OFFSET;
typedef enum
{
  FM_AUTO_VEN_PARAM_BASE  = 0,
  FM_AUTO_RCV_FILTER_BASE = 4, 
  FM_AOAA_VEN_PARAM_BASE  = 8,
  FM_AOAA_ISD_PARAM_BASE  = 0x0C    
} en_chip_ALG_PARAM_OFFSET;
typedef struct {
    uint32_t auto_ven_version;
    uint32_t aoaa_sw_version;
    uint32_t aoaa_ven_version;
    uint32_t isd_sw_version;
    uint32_t im301_lib_version;
} dsp_SW_VER;
typedef struct {
    uint32_t auto_ven_base;
    uint32_t auto_rcv_fliter_base;  
    uint32_t aoaa_ven_base;
    uint32_t aoaa_isd_base;
} dsp_SW_BASE;
typedef enum
{
  SPI_IM_RD = 0x0,
  SPI_DM_RD = 0x1,
  SPI_REG_RD = 0x2,
  SPI_IM_WR = 0x4,
  SPI_DM_WR = 0x5,
  SPI_REG_WR = 0x6,
  SPI_DM_RD_CRC = 0x41,
  SPI_DM_WR_CRC = 0x45,
  SPI_IM_RD_CRC = 0x40,
  SPI_IM_WR_CRC = 0x44
} dsp_cmd;
typedef enum
{
  dsp_onoff = 0,
  interrupt_dsp = 1
} dsp_SPI_REG;
typedef enum
{
  SYS_INIT_CNT  = 0,
  SYS_DBG_STA   = 4, 
  SYS_DBG_PC    = 8,
  SYS_ID_INFO   = 28        
} en_chip_SYS_DBG_OFFSET;
typedef enum
{
  DSP_PARAM_TX  = 1,  
  DSP_PARAM_RX,       
  DSP_PARAM_DEBUG,    
  DSP_PARAM_HW,       
  DSP_PARAM_AFE,      
  DSP_PARAM_SYS       
} en_param_type;
typedef enum
{
    VEN_INDEX_TX = 0,
    VEN_INDEX_RX = 0x2A0,
    VEN_INDEX_DEBUG = 0x330        
} en_chip_VEN_INDEX;
typedef struct
{
  uint32_t ven_param_base;
  uint32_t debug_param_base;
  uint32_t afe_param_base;
  uint32_t sys_param_base;
} st_dsp_addr;
typedef struct {
    uint32_t addr;
    uint32_t value;
} reg_config_t;
typedef enum
{
  dsp_mode1 = 1, 
  dsp_mode2 = 2  
} en_chip_mode;
void codec_hw_reset(void);
void dsp_hw_reset(void);
void dsp_sw_reset(void);
void dsp_fw_version(void);
void dsp_sw_version(void);
void dsp_send_bin_data(const uint8_t *pData);
void dsp_write_mode_param(en_param_type param_type, const reg_config_t register_config[], 
                                          const size_t register_config_size);
void dsp_download_bins(void);
bool dsp_switch_mode_set(void);
void dsp_run_dsp(void);
bool dsp_check_run(void);

/**
*********************************************************************************************************
* @brief 实现毫秒级延时
* @param n_ms 需要延时的毫秒数
*********************************************************************************************************/
void dsp_delay_ms(uint32_t n_ms);
/**
*********************************************************************************************************
* @brief DSP芯片初始化和启动
* @retval bool - 初始化结果
*         @arg true  : DSP初始化成功并正常运行
*         @arg false : DSP初始化失败或未响应
*********************************************************************************************************/
bool dsp_init(void);
/**
*********************************************************************************************************
* @brief 切换dsp芯片工作模式
* @param mode 目标工作模式，支持以下模式：
*        - mode_16k_LIN_SRCon
*        - mode_8k_LIN_SRCon
* @retval bool - 切换DSP芯片工作模式结果
*         @arg true  : 切换成功
*         @arg false : 切换失败
*********************************************************************************************************/
bool dsp_switch_mode(en_chip_mode mode);
#ifdef __cplusplus
}
#endif
#endif
#endif
